home *** CD-ROM | disk | FTP | other *** search
/ Amiga CD-ROM Collection / Amiga CD-ROM Collection - Auge 4000 and Cactus and Demo Util.iso / auge4000 / 12 / fraktalekarten / atv.c < prev    next >
C/C++ Source or Header  |  1987-05-31  |  14KB  |  414 lines

  1.  
  2. #include "atv.h"
  3.  
  4. extern struct Requester req;            /* custom requester structure */ 
  5. extern struct Border out_border;
  6. extern struct Gadget ongad;
  7. extern struct Gadget offgad;
  8.  
  9. extern short autoEnquire();
  10.  
  11. /*
  12.  * sc.c - fractalish terrain generator.
  13.  *
  14.  *   Date:     March 5, 1987 (original version sometime in 1985)
  15.  *   Author:   Chris Gray
  16.  *   Language: C
  17.  *   System:   Amiga
  18.  */
  19.  
  20. /*
  21.  * Badly hacked for Dynamic allocation under 16-bit integer Manx:
  22.  *
  23.  *   Date:        July 6, 1987
  24.  *   Barbarian:   Howard Hull
  25.  *   Implements:  (some) Dynamic allocation code from Ray Bovet
  26.  *                (considerable) custom requester code from John Draper's
  27.  *                 gadget tutorial
  28.  */
  29.  
  30. /*
  31.  * Gray: (continued, but edited for current content)
  32.  *
  33.  * The nature of the terrain can be changed by playing with the numbers
  34.  * in 'Range'. If you change SIZE, you must also change the number of
  35.  * values given for 'Range'.  The created terrain for SIZE = 8 and PGEOM
  36.  * set to SINGLEW is 256 pixels by 256 pixels, which doesn't fit on a
  37.  * non-interlaced screen, so only the top 200 pixels are displayed.  The
  38.  * terrain is a torus, i.e. wraps around both vertically and horizontally.
  39.  * To see the whole torus in a rectangular format, use SIZE = 7 and set
  40.  * PGEOM to DOUBLEW.  For other combinations see instructions below.
  41.  */
  42.  
  43. /*
  44.  * Feel free to use this algorithm in any games you write, so long as you
  45.  * give me [Gray] credit for it.
  46.  * Gray says: (I THINK I invented it, since I've never heard of anything
  47.  * similar, and other programs I've seen use much slower methods.)
  48.  */
  49.  
  50. #define SINGLEW 1            /* Use to obtain "square" pixel map            */
  51. #define DOUBLEW 2            /* Use to obtain "wide rectangular" pixel map  */
  52. #define PGEOM  DOUBLEW        /* Selects picture geometry.  Picture size is  */
  53. #define SIZE 7                /* 128 X 128 for 7 at SINGLEW, or 256 X 128 at */
  54. #define MAPH (1 << SIZE)    /* 7 in DOUBLEW.  MAPH is map height, or 128   */
  55. #define MAPW (MAPH*PGEOM)    /* for 7 SIZE, 256 for 8 SIZE config as torus  */
  56. #define CAMOD 4                /* SIZE 7 always 4, SIZE 8 & DOUBLEW must be 8 */
  57. #define MAPMH MAPH/CAMOD    /* sets calloc module size; calloc is 16-bit!  */
  58. #define CSIZE 2                /* calloc needs to know short type is 2 bytes  */
  59. #define SCREEN_WIDTH 320    /* 320X200: 7 & SINGLEW 32K, looks 1/4 size    */
  60. #define SCREEN_HEIGHT 200    /* 320X200: 7 & DOUBLEW 65K, 8 & SINGLEW 131K  */
  61.                             /* 320X400: 8 & SINGLEW 131K, 8 & DOUBLEW 262K */
  62.                             /* 640X200: 8 & SINGLEW 131K, 8 & DOUBLEW 262K */
  63.                             /* 640X400: 8 & DOUBLEW 262K looks 1/4 size    */
  64. #define SCREEN_DEPTH 5L        /* use 4L max for interlaced screens!          */
  65. #define COLOURS (long)(1 << SCREEN_DEPTH)    /* up to 32 colors             */
  66. #define WINDOW_WIDTH (long)(MAPW < SCREEN_WIDTH ? MAPW : SCREEN_WIDTH)
  67. #define WINDOW_HEIGHT (long)(MAPH < SCREEN_HEIGHT ? MAPH : SCREEN_HEIGHT)
  68. #define REQ_LEFT_EDGE 256L    /* Position of enquirer  window when called    */
  69. #define REQ_TOP_EDGE 12L    /* up on the terrain display's screen          */
  70. #define REQ_WIDTH 64L       /* Width of enquirer window */
  71. #define REQ_HEIGHT 72L     /* Length of enquirer window */
  72.  
  73. #define FREEPEN (-1)
  74.  
  75. static unsigned short Range[SIZE] = {38, 36, 36, 12, 8, 4, 2};
  76. /* static unsigned short Range[SIZE] = {38, 36, 36, 36, 12, 8, 4, 2}; SIZE 8 */
  77.  
  78. /* Color table for non-interlaced screen */
  79. static unsigned short ColourMap[COLOURS] = {
  80.     0x00f, 0x050, 0x070, 0x0a0, 0x0c0, 0x0e0, 0x4f4, 0x8f8,
  81.     0xdf0, 0xff0, 0xbd2, 0x9c3, 0x6b5, 0x4a6, 0x297, 0x088,
  82.     0x078, 0x177, 0x366, 0x465, 0x663, 0x762, 0x951, 0xa50,
  83.     0xa62, 0xa74, 0xa86, 0xa98, 0xaaa, 0xccc, 0xeee, 0xfff
  84. };
  85. /* AutoEnquire body and button texts */
  86. struct IntuiText negtext =
  87.     {COLOURS - 1L, 0L, JAM2, 5L, 2L, NULL, NULL, NULL};
  88. struct IntuiText postext =
  89.     {COLOURS - 1L, 0L, JAM2, 5L, 2L, NULL, NULL, NULL};
  90. struct IntuiText text =
  91.     {COLOURS - 1L, 0L, JAM2, 12L, 7L, NULL, NULL, NULL};
  92.  
  93. short wleftedge = -1; /* These are the variables in which we     */
  94. short wtopedge = -1;  /* get the first moved enquirer position.  */
  95.  
  96. static unsigned short Seed;
  97. static short altitude;
  98. short interested;
  99.  
  100. short *Cell[MAPH];  /* define an array of pointers to modules from calloc */
  101. char *calloc();        /* define the allocator subroutine call */
  102.  
  103. /*
  104.  * random - return a random number 0 - passed range.
  105.  */
  106.  
  107. unsigned short random(rang)
  108. unsigned short rang;
  109. {
  110.     if (rang == 0)
  111.         return 0;
  112.     Seed = Seed * 17137 + 4287;
  113.     Seed = (Seed >> 8) ^ (Seed << 8);
  114.     return Seed % rang;
  115. }
  116.  
  117. /*
  118.  * set - set a given spot in Cell.
  119.  */
  120.  
  121. void set(size, height)
  122. unsigned short size;
  123. short height;
  124. {
  125.     unsigned short rang;
  126.  
  127.     rang = Range[size];
  128.     height = height + random(rang) - (rang + 1) / 2;
  129.     altitude = height;
  130. }
  131.  
  132. struct IntuitionBase *IntuitionBase;
  133. struct GfxBase       *GfxBase;
  134.  
  135. /*
  136.  * main program.
  137.  */
  138.  
  139. void main()
  140. {
  141.  
  142.     unsigned short i, j, k, l, m;
  143.     unsigned short c, step, nextStep, l1, l2, c1, c2;
  144.     short height;
  145.  
  146.     struct DateStamp ds;
  147.  
  148. /* this is the terrain screen.  See RKM for 320X400 & 640X200 configs */
  149.     static struct NewScreen newScreen =
  150.           {0L, 0L, SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_DEPTH, 0L, 1L,
  151.           0x0, CUSTOMSCREEN, NULL, NULL, NULL, NULL};
  152.  
  153. /* this is the terrain display's window structure */
  154.     static struct NewWindow newWindow =
  155.             {
  156.             0L, 0L, WINDOW_WIDTH, WINDOW_HEIGHT,
  157.             FREEPEN, FREEPEN,
  158.             0x0, BORDERLESS | ACTIVATE | NOCAREREFRESH,
  159.             NULL, NULL, NULL, NULL, NULL, 0L, 0L, 0L, 0L,
  160.             CUSTOMSCREEN
  161.             };
  162.  
  163. /* this is the AutoEnquire window structure */
  164.     static struct NewWindow reqWindow =
  165.             {
  166.             REQ_LEFT_EDGE, REQ_TOP_EDGE, REQ_WIDTH, REQ_HEIGHT,
  167.             FREEPEN, FREEPEN,
  168.               CLOSEWINDOW            /*  IDCMP flags                      */
  169.             | REFRESHWINDOW
  170.             | MOUSEBUTTONS
  171.             | REQCLEAR 
  172.             | GADGETDOWN 
  173.             | SELECTDOWN 
  174.             | SELECTUP, 
  175.                                      /*  Usual flags for gadgets and such */ 
  176.               ACTIVATE
  177.             | WINDOWDEPTH 
  178.             | WINDOWDRAG 
  179.             | SMART_REFRESH, 
  180.             NULL, NULL, NULL, NULL, NULL, 0L, 0L, 0L, 0L,
  181.             CUSTOMSCREEN
  182.             };
  183.  
  184. /* 'main' assignments begin here */
  185.  
  186. /* **************************************************************************
  187. *                                                                            *
  188. *  :::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  189. *  ::  When you're up to your OS in allocators, it's hard ::                *
  190. *  :: to remember that the task was to empty /dev/swap... ::                *
  191. *  :::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  192. *                                                                            *
  193. *  I ransacked some of Ray Bovet's Atari code to get the dynamic allocator. *
  194. *  However, on my own I discovered Horror #1:                                *
  195. *                                                                            *
  196. *  Dynamic allocation for Manx uses either of two Unix compatible routines,    *
  197. *  malloc or calloc from the system independent library.  Since calloc        *
  198. *  merely multiplies its two input arguments and uses them to call malloc,    *
  199. *  with a 16-bit integer compiler the maximum request is 65,535 bytes.        *
  200. *  Requests for 65,536 bytes get zero bytes allocated.  In order to obtain    *
  201. *  262,144 bytes we would have to ask malloc for eight 32,768 byte modules.    *
  202. *                                                                            *
  203. *  Just to be decent, this code was issued with #defines at the front that    *
  204. *  will ask (as printed) for four modules.  Change the #define for CAMOD to *
  205. *  experiment with this.                                                    *
  206. *  Good Luck...                                                        H. Hull *
  207. *                                                                            *
  208. ************************************************************************** */
  209.  
  210. /* Dynamic allocation routine for terrain growth arrays */
  211.  
  212. /* casts input arguments to their required types */
  213. /* typedef for UINT 'unsigned integer' is at top of page */
  214. /* cast the char pointer returned to type 'short *' for our use in Cell */
  215. /* calloc returns arg1 items of size arg2, cleared to zeros */
  216.  
  217. k = 0;
  218. do
  219.     {
  220.     if ((Cell[k] = (short *)calloc((UINT)(MAPMH*MAPW), (UINT)CSIZE)) == NULL)
  221.         {
  222.         exit(0);  /* Silently exits.  Anybody know a more graceful method? */
  223.     }
  224. }
  225.  
  226. /* MAPMH is module 'height' in the window; */
  227. /* an even number of modules stack together like blind slats on the window */
  228.  
  229. /* Each module produces a pointer to its base that goes into Cell[0] so   */
  230. /* we have to then fill the Cell array with window height-based pointers  */
  231. /* one pointer for each line across the window.  These serve as pointers  */
  232. /* to window-width based line data we want to put in the returned module. */
  233.  
  234. while ((k = k + MAPMH) < MAPH);
  235.  
  236. for (k = 1; k <= CAMOD; k++)
  237.     {
  238.     l = MAPMH*k;
  239.     m = MAPMH*(k-1);
  240.     for (j = m+1; j < l; j++)
  241.            {
  242.         Cell[j] = Cell[j-1] + MAPW;        /* makes an array of pointers */
  243.     }
  244. }
  245.  
  246. /* Back to the original programe now... */
  247.  
  248.     IntuitionBase = (struct IntuitionBase *)
  249.                             OpenLibrary("intuition.library", 0L);
  250.     if (IntuitionBase != NULL)
  251.         {
  252.         GfxBase = (struct GfxBase *)
  253.                           OpenLibrary("graphics.library", 0L);
  254.         if (GfxBase != NULL)
  255.             {
  256.             Screen = OpenScreen(&newScreen);
  257.             if (Screen != NULL)
  258.                 {
  259.                 LoadRGB4(&Screen->ViewPort, ColourMap, COLOURS);
  260.                 newWindow.Screen = Screen;
  261.                 Window = OpenWindow(&newWindow);
  262.                 if (Window != NULL)
  263.                     {
  264.                     DateStamp(&ds);
  265.                     Seed = (ds.ds_Minute ^ ds.ds_Tick) | 1;
  266.  
  267. /*  Ok.  I give up.  I notice that Cell[y][x] in main() is a place to put */
  268. /* a single data point, even though Cell is actually a singly subscripted */
  269. /* array of pointers.  We certainly wouldn't want to smash the pointer by */
  270. /* attempting an assignment of data to Cell[n].  The compiler would warn  */
  271. /* about a short to pointer conversion, anyway.  We could use *Cell[n] to */
  272. /* obtain the quantity in the base cell of any particular line of data,   */
  273. /* and pointer arithmetic (*Cell[y]+x) might (?) get us the data we want  */
  274. /* to access.  But when I try to use Cell[y][x] in a subroutine, I get an */
  275. /* excess array subscript error.  No amount of fiddling with subroutine   */
  276. /* argument definitions yielded any error free situation.  I can't use a  */
  277. /* 'static' definition in main for a dynamically allocated data element,  */
  278. /* either, can I?  So this program got hacked to where it looks like a    */
  279. /* meat packing plant after a company holiday.  No subroutines addressing */
  280. /* Cell are to be found within it.  Indentation is out the window, too.   */
  281.  
  282. do
  283. {
  284.  
  285. /*
  286.  * grow - grow the basic scenery heights.
  287.  */
  288.  
  289.     Cell[0][0] = 0;
  290.     step = MAPH;
  291.     for (i=0; i<SIZE; i++)
  292.         {
  293.         nextStep = step / 2;
  294.         for (l=0; l<MAPH; l+=step)
  295.             {
  296.             l1 = l + nextStep;
  297.             l2 = l + step;
  298.             if (l2 == MAPH)
  299.                 l2 = 0;
  300.             for (c=0; c<MAPW; c+=step)
  301.                 {
  302.                 c1 = c + nextStep;
  303.                 c2 = c + step;
  304.                 if (c2 == MAPW)
  305.                     c2 = 0;
  306.                 set(i, (Cell[l][c] + Cell[l][c2] + 1) / 2);
  307.                 Cell[l][c1] = altitude;
  308.                 set(i, (Cell[l][c] + Cell[l2][c] + 1) / 2);
  309.                 Cell[l1][c] = altitude;
  310.                 set(i, (Cell[l][c] + Cell[l][c2] +
  311.                                  Cell[l2][c] + Cell[l2][c2] + 2) / 4);
  312.                 Cell[l1][c1] = altitude;
  313.                 }
  314.             }
  315.         step = nextStep;
  316.         }
  317.  
  318. /*
  319.  * display - display the resulting scenery.
  320.  */
  321.  
  322.     for (l=0; l<WINDOW_HEIGHT; l++)
  323.         {
  324.         for (c=0; c<WINDOW_WIDTH; c++)
  325.             {
  326.             height = Cell[l][c];
  327.             SetAPen(Window->RPort,
  328.                     (long)(height<0 ?
  329.                         0
  330.                     : (height>=COLOURS ?
  331.                         COLOURS-1
  332.                     : height)));
  333.             WritePixel(Window->RPort, (long)c, (long)l);
  334.         }
  335.     }
  336.  
  337. interested = FALSE;
  338. reqWindow.Screen = Screen;
  339. if ((wleftedge >= 0) || (wtopedge >= 0))
  340.     {
  341.     reqWindow.LeftEdge = wleftedge;  /* if the window has been opened, */
  342.     reqWindow.TopEdge = wtopedge;    /* use the updated coordinates    */
  343. }
  344. RWindow = OpenWindow(&reqWindow);
  345. if (RWindow != NULL)
  346.     {
  347.     (void) InitRequester(&req);  /* Rumor: clears req structure entirely */
  348.  
  349.     /* Init the fields in the Requester structure */ 
  350.   
  351.     req.LeftEdge  = 4; 
  352.     req.TopEdge   = 12; 
  353.     req.Width     = 56; 
  354.     req.Height    = 59; 
  355.     req.ReqGadget = &ongad;         /* First gadget */
  356.     req.ReqText   = &text;          /* Text for enquirer */
  357.     req.BackFill  = 1;              /* BackGnd color to window */
  358.     req.Flags     = 0; 
  359.     req.ReqBorder = &out_border;    /* Must have at least one */
  360.  
  361.     /* initialize the enquirer text */
  362.  
  363.     text.IText = (unsigned char *)"DONE";
  364.     postext.IText = (unsigned char *)"NEXT";
  365.     negtext.IText = (unsigned char *)"QUIT";
  366.  
  367.     if (Request(&req, RWindow) == 1)  /* try to open the enquirer window */
  368.         {
  369.         interested = (autoEnquire());  /* if we're here it did open, so  */
  370.                             /* now we can find out what they want to do */
  371.  
  372. /* To aviod some the above cumbersome initialization, the following is a
  373.     model for the AutoEnquire function (for v1.3 anybody?) which allows us
  374.     to specify WHERE the requester will go rather than HOW BIG it will be:
  375.  
  376.         interested = (AutoEnquire
  377.                     (
  378.                     Window,
  379.                     BodyText,
  380.                     PositiveText,
  381.                     NegativeText,
  382.                     PositiveFlags,
  383.                     NegativeFlags,
  384.                     XPosition,
  385.                     YPosition
  386.                     )
  387.                 );
  388.    It should also be possible to set things up so that if the user moves
  389.     the AutoEnquire window, Intuition can keep track of where he put it
  390.     so that it will open up in the same place next time it's called.
  391.     Would you like that, Bunky?  Since Intuition maintains the structure,
  392.     it could be done with the appropriate flags.                    */
  393.  
  394.         CloseWindow(RWindow);  /* if we're here we got their attention */
  395.                               /* and we can close the enquirer window */
  396.     }
  397. }
  398. }
  399. while (interested == TRUE);
  400.  
  401. /* Ok.  We're back to normal now.  We're also all done with the program. */
  402. /* Time to clean up the mess and get out while we're still ahead...      */
  403.  
  404.                     CloseWindow(Window);
  405.                 }
  406.                 CloseScreen(Screen);
  407.             }
  408.             CloseLibrary(GfxBase);
  409.         }
  410.         CloseLibrary(IntuitionBase);
  411.     }
  412. }
  413.  
  414.